// 使用类的方式来封装请求方法
// 增加代码复用性 添加新的属性和方法
class WxRequest {
  // 默认参数对象
  defaults = {
    baseURL: '', // 请求基准地址
    url: '', // 开发者服务器接口地址
    data: null, // 请求参数
    method: 'GET', // 默认请求方法
    // 请求头
    header: {
      'Content-type': 'application/json' // 设置数据的交互格式
    },
    timeout: 60000, // 小程序默认超时时间是 60000，一分钟
    isloading: true //控制是否使用默认loading
  }
  // 定义拦截器对象
  interceptors = {
    // 请求拦截器
    request: (config) => config,
    // 响应拦截器
    response: (response) => response
  }
  queue = []
  // 实例化传入的参数
  constructor(params = {}) {
    this.defaults = Object.assign({}, this.defaults, params)
  }

  // request接受一个对象 和wx.request传递的参数保持一致
  request(options) {
    this.timerId && clearTimeout(this.timerId)
    options.url = this.defaults.baseURL + options.url
    options = { ...this.defaults, ...options }
    // console.log(options)
    if (options.isloading && options.method !== 'UPLOAD') {
      // 在请求之前 添加loading效果
      this.queue.length === 0 && wx.showLoading()
      // 立即向queue里加标识
      this.queue.push('request')
    }

    // 在请求之前调用拦截器
    options = this.interceptors.request(options)
    return new Promise((resolve, reject) => {
      if (options.method === 'UPLOAD') {
        wx.uploadFile({
          ...options,
          success: (res) => {
            res.data = JSON.parse(res.data)
            const mergeRes = Object.assign({}, res, {
              config: options,
              isSuccess: true
            })
            resolve(this.interceptors.response(mergeRes))
          },
          fail: (err) => {
            const mergeRes = Object.assign({}, err, {
              config: options,
              isSuccess: false
            })
            reject(this.interceptors.response(mergeRes))
          }
        })
      } else {
        wx.request({
          ...options,
          success: (res) => {
            // 不管是成功还是失败 都要用响应拦截器
            const mergeRes = Object.assign({}, res, {
              config: options,
              isSuccess: true
            })
            resolve(this.interceptors.response(mergeRes))
          },
          fail: (error) => {
            const mergeErr = Object.assign({}, error, {
              config: options,
              isSuccess: false
            })
            reject(this.interceptors.response(mergeErr))
          },
          complete: () => {
            if (options.isloading) {
              this.queue.pop()
              this.queue.length === 0 && this.queue.push('request')
              this.timerId = setTimeout(() => {
                this.queue.pop()
                // 将loading效果关闭
                this.queue.length === 0 && wx.hideLoading()
                clearTimeout(this.timerId)
              }, 1)
            }
          }
        })
      }
    })
  }
  // 请求便携方法
  get(url, data = {}, config = {}) {
    return this.request(Object.assign({ url, data, method: 'get' }, config))
  }
  post(url, data = {}, config = {}) {
    return this.request(Object.assign({ url, data, method: 'post' }, config))
  }
  delete(url, data = {}, config = {}) {
    return this.request(Object.assign({ url, data, method: 'delete' }, config))
  }
  put(url, data = {}, config = {}) {
    return this.request(Object.assign({ url, data, method: 'put' }, config))
  }
  all(...promise) {
    // 通过展开运算符接受传递的参数
    // 将传入的参数转换成数组
    return Promise.all(promise)
  }
  upload(url, filePath, name = 'file', config = {}) {
    return this.request(
      Object.assign({ url, filePath, name, method: 'UPLOAD' }, config)
    )
  }
}

export default WxRequest
